package com.desire.test;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.time.temporal.ChronoUnit;
import java.util.Locale;
import java.util.Set;

/**
 * @author LittleDesire
 * @description
 * @date 2022-02-10 周四 11:30
 * @since 17
 */
public class _59_日期API {
    /**
     * 在Java8以前，Date日期API对我们非常的不友好，它无法表示日期，只能以毫秒的精度来表示时间，
     * 并且可以修改，他的线程还不是安全的。所以Java8中引入了全新的日期和时间API就是为了解决这一问题。
     * java.util.Date 日期类
     * java.util.Calendar 日历
     * java.text.SimpleDateFormat 格式化类
     * java.time.LocalDate 年月日
     * java.time.LocalTime 时分秒
     * java.time.LocalDateTime 年月日时分秒
     * java.time.format.DateTimeFormatter 格式化 日期 时间 日期时间
     * 小时（h）分钟（min）秒（s）
     * 毫秒（ms）微秒（us）纳秒（ns）皮秒（ps）飞秒（fs）
     */

    /**
     * LocalDate、 LocalTime、 LocalDateTime以及Instant这样表示时间点的日期时间类提供了大量通用的方法。
     * <p>
     * 方法名	是否是静态方法	描述
     * form	    是	            根据传入的Temporal对象创建对象实例
     * now	    是	            根据系统时钟创建Temporal对象
     * of	    是	            由Temporal对象的某个部分创建该对象的实例
     * parse	是	            由字符串创建Temporal对象的实例
     * atOffset	否	            将Temporal对象和某个时区偏移相结合
     * atZone	否	            将Temporal对象和某个时区相结合
     * format	否	            使用某个指定的格式器将Temporal对象转化为字符串（Instant 类不提供该方法）
     * get	    否	            读取Temporal对象某一个部分的值
     * minus	否	            创建Temporal对象的一个副本，通过将当前Temporal对象的值减去一定的时长创建该副本
     * plus	    否	            创建Temporal对象的一个副本，通过将当前Temporal对象的值加上一定的时长创建该副本
     * with	    否	            以该Temporal对象对象为模板，对某些状态进行修改创建该对象的副本
     */
    @Test
    @DisplayName("LocalDate年月日")
    public void test1() {
        // 设置年与日
        LocalDate of = LocalDate.of(2022, 2, 10);
        System.out.println(of);
        //年份 2022
        System.out.println(of.getYear());
        //月份 2
        System.out.println(of.getMonthValue());
        //这个月的第几天 10
        System.out.println(of.getDayOfMonth());
        //这周的第几天 4
        System.out.println(of.getDayOfWeek().getValue());
        //这年的第几天 41
        System.out.println(of.getDayOfYear());
        // 是否是闰年 false
        System.out.println(of.isLeapYear());
        // 2022-02-10
        System.out.println(LocalDate.now());
        LocalDate now = LocalDate.now();
        // 2022-02-11
        LocalDate localDate = now.plusDays(1);
        System.out.println(localDate);
        // 2022-02-12
        LocalDate plus = now.plus(2, ChronoUnit.DAYS);
        System.out.println(plus);

        LocalDate independenceDay = LocalDate.of(2014, Month.JULY, 4);
        DayOfWeek dayOfWeek = independenceDay.getDayOfWeek();
        // 5  2014年7月4号 是星期5
        System.out.println(dayOfWeek.getValue());

        // 多种工厂方法简化对象创建,包括字符串的解析
        DateTimeFormatter germanFormatter = DateTimeFormatter
                .ofLocalizedDate(FormatStyle.MEDIUM)
                .withLocale(Locale.GERMAN);
        LocalDate xmas = LocalDate.parse("01.11.2019", germanFormatter);
        // 2019-11-01
        System.out.println(xmas);
    }

    /**
     * Full text style, with the most detail.
     * For example, the format might be 'Tuesday, April 12, 1952 AD' or '3:30:42pm PST'.
     * FULL,
     * Long text style, with lots of detail.
     * For example, the format might be 'January 12, 1952'.
     * LONG,
     * Medium text style, with some detail.
     * For example, the format might be 'Jan 12, 1952'.
     * MEDIUM,
     * Short text style, typically numeric.
     * For example, the format might be '12.13.52' or '3:30pm'.
     * SHORT;
     */
    @DisplayName("localTime时分秒")
    @Test
    public void test2() {
        LocalTime localTime = LocalTime.of(11, 12, 13);
        //小时：11
        System.out.println(localTime.getHour());
        //分钟：12
        System.out.println(localTime.getMinute());
        //秒数：13
        System.out.println(localTime.getSecond());

        //  //获取两个时间时间差
        long h = ChronoUnit.HOURS.between(localTime, LocalTime.now());
        long m = ChronoUnit.SECONDS.between(localTime, LocalTime.now());
        System.out.println(h);
        System.out.println(m);

        // 多种工厂方法简化对象创建,包括字符串的解析
        // 定义解析方式
        DateTimeFormatter dtf = DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT).withLocale(Locale.GERMAN);
        LocalTime parse = LocalTime.parse("12:24", dtf);
        System.out.println(parse);
    }

    @Test
    @DisplayName("localDateTime日期")
    public void test3() {
        //2019-11-12T13:14:15
        LocalDateTime localDateTime = LocalDateTime.of(2019, 11, 12, 13, 14, 15);
        //2019-11-12
        System.out.println(localDateTime.toLocalDate());
        //13:14:15
        System.out.println(localDateTime.toLocalTime());
        //可以从LocalDateTime获取所有的当前的信息，比如，年份，月份。。
        //获取当前系统的日期，时间
        System.out.println(LocalDateTime.now());
        // Zone -要使用的时区，不为空
        LocalDateTime date = LocalDateTime.parse("2017-02-03T12:30:30");
        System.out.println(date);
        ZonedDateTime date1 = date.atZone(ZoneId.of("Asia/Shanghai"));
        // 2017-02-03T12:30:30+08:00[Asia/Shanghai]
        System.out.println(date1);

        // 获取这一天是周几
        System.out.println(localDateTime.getDayOfWeek().getValue());
    }

    @Test
    @DisplayName("localDateTimeFormat")
    public void test4() {
        LocalDateTime localDateTime = LocalDateTime.now();
        System.out.println(localDateTime.format(DateTimeFormatter.BASIC_ISO_DATE));
        //20220210
        System.out.println(localDateTime.format(DateTimeFormatter.ISO_DATE_TIME));
        //2022-02-10T15:02:18.887067
        System.out.println(localDateTime.format(DateTimeFormatter.ISO_DATE));
        //2022-02-10
        System.out.println(localDateTime.format(DateTimeFormatter.ISO_TIME));
        //15:02:18.887067

        //自定义规则
        System.out.println(localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        //2022-02-10 15:02:18
        System.out.println(localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        //2022-02-10
        System.out.println(localDateTime.format(DateTimeFormatter.ofPattern("HH:mm:ss")));
        //15:02:18

        //解晰字符串
        String myDateTime = "2019-12-10 09:39:18";
        String myDate = "2019-12-10";
        System.out.println(LocalDate.parse(myDate, DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        //2019-12-10
        System.out.println(LocalDateTime.parse(myDateTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        //2019-12-10T09:39:18
    }

    @Test
    @DisplayName("Clock")
    public void test5() {
        Clock clock = Clock.systemDefaultZone();
        // SystemClock[Asia/Shanghai] 时区
        System.out.println(clock);
        // 1644477292893
        System.out.println(clock.millis());
        // 2022-02-10T07:14:52.894890700Z
        System.out.println(clock.instant());
        // Asia/Shanghai
        System.out.println(clock.getZone());
        // SystemClock[Asia/Shanghai]
        System.out.println(clock.withZone(ZoneId.of("Asia/Shanghai")));
        //SystemClock[Z]
        System.out.println(Clock.systemUTC());
    }

    @Test
    @DisplayName("timezones时区")
    public void test6() {
        Set<String> zoneIds = ZoneId.getAvailableZoneIds();
        // 打印出所有时区
        // zoneIds.forEach(System.out::println);
        ZoneId of = ZoneId.of("Asia/Shanghai");
        //亚丁湾
        ZoneId of1 = ZoneId.of("Asia/Aden");
        // ZoneRules[currentStandardOffset=+08:00]
        // ZoneRules[currentStandardOffset=+03:00]
        System.out.println(of.getRules());
        System.out.println(of1.getRules());
    }

    @Test
    @DisplayName("Instant")
    public void test7() {
        Instant instant = Instant.now();
        // 2022-02-10T11:24:17.150824600Z
        System.out.println(instant);

        //1644492353 秒
        System.out.println(instant.getEpochSecond());

        //毫秒 1644492411943
        System.out.println(instant.toEpochMilli());


    }

    @Test
    @DisplayName("DateTimeFormatter")
    public void test8() {
        var d2 = LocalDate.now();
        System.out.println(d2);
        System.out.println(d2.format(DateTimeFormatter.BASIC_ISO_DATE));
        System.out.println(d2.format(DateTimeFormatter.ISO_DATE));
        System.out.println(d2.format(DateTimeFormatter.ISO_LOCAL_DATE));
        System.out.println(d2.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日")));
        System.out.println(d2.format(DateTimeFormatter.ofPattern("E")));
        //2022-02-10
        //20220210
        //2022-02-10
        //2022-02-10
        //2022年02月10日
        //周四


        var t2 = LocalTime.now();
        t2 = LocalTime.of(12, 33, 32);
        System.out.println(t2);
        var dtf = DateTimeFormatter.ofPattern("HH:mm:ss");
        System.out.println(t2.format(dtf));
        var d3 = LocalDateTime.now();
        var d3f = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss E");
        System.out.println(d3.format(d3f));
        //12:33:32
        //12:33:32
        //2022-02-10 19:37:57 周四
    }
}
